#include "common.h"

extern int tcp_disconnect(struct sock *sk, int flags);
static int my_tcp_disconnect(struct sock *sk, int flags)
{
    int ret;
	struct tcp_sock *tp = tcp_sk(sk);
    
    printk(KERN_DEBUG "%s state = %d, snd_nxt = %d, write_seq = %d\n",
        __FUNCTION__, sk->sk_state, tp->snd_nxt, tp->write_seq);
    
    memcpy(target_func, saved_st, 4 * NUM_NEED);
    clean_cache(target_func, target_func + NUM_NEED);

    ret = tcp_disconnect(sk, flags);
    
	hijack_func();
    return (ret);
}

void jmpfunc(void)
{
    __asm__ __volatile__ ("mov %%pc, %0"
                          ::"r"((void *)my_tcp_disconnect));    
}


int tcp_disconnect_init(void)
{
    target_func = tcp_disconnect;
    printk(KERN_DEBUG "%s init\n", __FUNCTION__);
    save_old(target_func);
	hijack_func();
    return 0;
}

void tcp_disconnect_exit(void)
{
    memcpy((void *)target_func, saved_st, 4 * NUM_NEED);
    clean_cache((void *)target_func, (void *)target_func + NUM_NEED);    
	printk(KERN_DEBUG "%s exit\n", __FUNCTION__);
}

module_init(tcp_disconnect_init);
module_exit(tcp_disconnect_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("tpl.a1406@gmail.com");


